home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / DB.PAK / DBCTL.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  10KB  |  384 lines

  1. // dbctl.cpp : Implementation of the CDbCtrl OLE control class.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1995 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "db.h"
  15. #include "dbctl.h"
  16. #include "dbppg.h"
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char BASED_CODE THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23.  
  24. IMPLEMENT_DYNCREATE(CDbCtrl, COleControl)
  25.  
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Message map
  29.  
  30. BEGIN_MESSAGE_MAP(CDbCtrl, COleControl)
  31.     //{{AFX_MSG_MAP(CDbCtrl)
  32.     // NOTE - ClassWizard will add and remove message map entries
  33.     //    DO NOT EDIT what you see in these blocks of generated code !
  34.     ON_OLEVERB(IDS_PROPERTIESVERB, OnProperties)
  35.     ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
  36.     //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38.  
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // Dispatch map
  42.  
  43. BEGIN_DISPATCH_MAP(CDbCtrl, COleControl)
  44.     //{{AFX_DISPATCH_MAP(CDbCtrl)
  45.     DISP_PROPERTY_NOTIFY(CDbCtrl, "Query", m_query, OnQueryChanged, VT_BSTR)
  46.     DISP_PROPERTY_NOTIFY(CDbCtrl, "DataSource", m_dataSource, OnDataSourceChanged, VT_BSTR)
  47.     DISP_PROPERTY_NOTIFY(CDbCtrl, "TableName", m_tableName, OnTableNameChanged, VT_BSTR)
  48.     DISP_PROPERTY_NOTIFY(CDbCtrl, "ColumnName", m_columnName, OnColumnNameChanged, VT_BSTR)
  49.     DISP_PROPERTY_NOTIFY(CDbCtrl, "UserName", m_userName, OnUserNameChanged, VT_BSTR)
  50.     DISP_PROPERTY_NOTIFY(CDbCtrl, "Password", m_password, OnPasswordChanged, VT_BSTR)
  51.     DISP_FUNCTION(CDbCtrl, "ReQuery", ReQuery, VT_EMPTY, VTS_NONE)
  52.     //}}AFX_DISPATCH_MAP
  53.     DISP_FUNCTION_ID(CDbCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
  54. END_DISPATCH_MAP()
  55.  
  56.  
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Event map
  59.  
  60. BEGIN_EVENT_MAP(CDbCtrl, COleControl)
  61.     //{{AFX_EVENT_MAP(CDbCtrl)
  62.     // NOTE - ClassWizard will add and remove event map entries
  63.     //    DO NOT EDIT what you see in these blocks of generated code !
  64.     //}}AFX_EVENT_MAP
  65. END_EVENT_MAP()
  66.  
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. //
  70.  
  71. IMPLEMENT_DYNAMIC(CGenericSet, CRecordset)
  72.  
  73. CString CGenericSet::GetDefaultSQL()
  74. {
  75.     return GetSQL();
  76. }
  77.  
  78. CGenericSet::CGenericSet(CDatabase* pDB, CString* pstrColumnName)
  79.     : CRecordset(pDB)
  80. {
  81.     ASSERT(pDB != NULL);
  82.     m_strColumnName = *pstrColumnName;
  83.     m_nFields = 1;
  84. }
  85.  
  86. void CGenericSet::DoFieldExchange(CFieldExchange* pFX)
  87. {
  88.     pFX->SetFieldType(CFieldExchange::outputColumn);
  89.      RFX_Text(pFX, m_strColumnName, m_strCurrentValue);
  90. }
  91.  
  92.  
  93. /////////////////////////////////////////////////////////////////////////////
  94. // Property pages
  95.  
  96. BEGIN_PROPPAGEIDS(CDbCtrl, 1)
  97.     PROPPAGEID(CDbPropPage::guid)
  98. END_PROPPAGEIDS(CDbCtrl)
  99.  
  100.  
  101. /////////////////////////////////////////////////////////////////////////////
  102. // Initialize class factory and guid
  103.  
  104. IMPLEMENT_OLECREATE_EX(CDbCtrl, "DB.DbCtrl.1",
  105.     0xeff01745, 0x7825, 0x101b, 0x83, 0x75, 0x0, 0xaa, 0x0, 0x37, 0x3f, 0xb9)
  106.  
  107.  
  108. /////////////////////////////////////////////////////////////////////////////
  109. // Type library ID and version
  110.  
  111. IMPLEMENT_OLETYPELIB(CDbCtrl, _tlid, _wVerMajor, _wVerMinor)
  112.  
  113.  
  114. /////////////////////////////////////////////////////////////////////////////
  115. // Interface IDs
  116.  
  117. const IID BASED_CODE IID_DDb =
  118.         { 0xeff01746, 0x7825, 0x101b, { 0x83, 0x75, 0x0, 0xaa, 0x0, 0x37, 0x3f, 0xb9 } };
  119. const IID BASED_CODE IID_DDbEvents =
  120.         { 0xeff01747, 0x7825, 0x101b, { 0x83, 0x75, 0x0, 0xaa, 0x0, 0x37, 0x3f, 0xb9 } };
  121.  
  122.  
  123.  
  124.  
  125.  
  126. /////////////////////////////////////////////////////////////////////////////
  127. // Control type information
  128.  
  129. static const DWORD BASED_CODE _dwDbOleMisc =
  130.     OLEMISC_ACTIVATEWHENVISIBLE |
  131.     OLEMISC_SETCLIENTSITEFIRST |
  132.     OLEMISC_INSIDEOUT |
  133.     OLEMISC_CANTLINKINSIDE |
  134.     OLEMISC_RECOMPOSEONRESIZE;
  135.  
  136. IMPLEMENT_OLECTLTYPE(CDbCtrl, IDS_DB, _dwDbOleMisc);
  137.  
  138.  
  139. /////////////////////////////////////////////////////////////////////////////
  140. // CDbCtrl::CDbCtrlFactory::UpdateRegistry -
  141. // Adds or removes system registry entries for CDbCtrl
  142.  
  143. BOOL CDbCtrl::CDbCtrlFactory::UpdateRegistry(BOOL bRegister)
  144. {
  145.     if (bRegister)
  146.         return AfxOleRegisterControlClass(
  147.             AfxGetInstanceHandle(),
  148.             m_clsid,
  149.             m_lpszProgID,
  150.             IDS_DB,
  151.             IDB_DB,
  152.             TRUE,                        //  Insertable
  153.             _dwDbOleMisc,
  154.             _tlid,
  155.             _wVerMajor,
  156.             _wVerMinor);
  157.     else
  158.         return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  159. }
  160.  
  161.  
  162. /////////////////////////////////////////////////////////////////////////////
  163. // CDbCtrl::CDbCtrl - Constructor
  164.  
  165. CDbCtrl::CDbCtrl()
  166. {
  167.     InitializeIIDs(&IID_DDb, &IID_DDbEvents);
  168.  
  169.     m_bConnected = FALSE;
  170.     m_pRecordSet = NULL;
  171. }
  172.  
  173.  
  174. /////////////////////////////////////////////////////////////////////////////
  175. // CDbCtrl::~CDbCtrl - Destructor
  176.  
  177. CDbCtrl::~CDbCtrl()
  178. {
  179.     if (m_pRecordSet != NULL)
  180.     {
  181.         m_pRecordSet->Close();
  182.         delete m_pRecordSet;
  183.         m_pRecordSet = NULL;
  184.     }
  185.  
  186.     if (m_bConnected == TRUE)
  187.     {
  188.         m_cDatabase.Close();
  189.     }
  190. }
  191.  
  192.  
  193. /////////////////////////////////////////////////////////////////////////////
  194. // CDbCtrl::OnDraw - Drawing function
  195.  
  196. void CDbCtrl::OnDraw(
  197.             CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */)
  198. {
  199.     DoSuperclassPaint(pdc, rcBounds);
  200. }
  201.  
  202.  
  203. /////////////////////////////////////////////////////////////////////////////
  204. // CDbCtrl::DoPropExchange - Persistence support
  205.  
  206. void CDbCtrl::DoPropExchange(CPropExchange* pPX)
  207. {
  208.     ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  209.     COleControl::DoPropExchange(pPX);
  210. }
  211.  
  212.  
  213. /////////////////////////////////////////////////////////////////////////////
  214. // CDbCtrl::OnResetState - Reset control to default state
  215.  
  216. void CDbCtrl::OnResetState()
  217. {
  218.     COleControl::OnResetState();  // Resets defaults found in DoPropExchange
  219. }
  220.  
  221.  
  222. /////////////////////////////////////////////////////////////////////////////
  223. // CDbCtrl::AboutBox - Display an "About" box to the user
  224.  
  225. void CDbCtrl::AboutBox()
  226. {
  227.     CDialog dlgAbout(IDD_ABOUTBOX_DB);
  228.     dlgAbout.DoModal();
  229. }
  230.  
  231.  
  232. /////////////////////////////////////////////////////////////////////////////
  233. // CDbCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
  234.  
  235. BOOL CDbCtrl::PreCreateWindow(CREATESTRUCT& cs)
  236. {
  237.     cs.lpszClass = _T("LISTBOX");
  238.     cs.style |= LBS_NOINTEGRALHEIGHT;
  239.     return COleControl::PreCreateWindow(cs);
  240. }
  241.  
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // CDbCtrl::GetSuperWndProcAddr - Provide storage for window proc
  245.  
  246. WNDPROC* CDbCtrl::GetSuperWndProcAddr(void)
  247. {
  248.     static WNDPROC NEAR pfnSuper;
  249.     return &pfnSuper;
  250. }
  251.  
  252.  
  253. /////////////////////////////////////////////////////////////////////////////
  254. // CDbCtrl::OnOcmCommand - Handle command messages
  255.  
  256. LRESULT CDbCtrl::OnOcmCommand(WPARAM  wParam, LPARAM lParam)
  257. {
  258.     WORD wNotifyCode = HIWORD(wParam);
  259.     lParam;
  260.  
  261.     return 0;
  262. }
  263.  
  264.  
  265. /////////////////////////////////////////////////////////////////////////////
  266. // CDbCtrl message handlers
  267.  
  268. void CDbCtrl::OnDataSourceChanged() 
  269. {
  270.     SetModifiedFlag();
  271. }
  272.  
  273. void CDbCtrl::OnTableNameChanged() 
  274. {
  275.     SetModifiedFlag();
  276. }
  277.  
  278. void CDbCtrl::OnColumnNameChanged() 
  279. {
  280.     SetModifiedFlag();
  281.         
  282. }
  283.  
  284. void CDbCtrl::OnUserNameChanged() 
  285. {
  286.     SetModifiedFlag();
  287. }
  288.  
  289. void CDbCtrl::OnPasswordChanged() 
  290. {
  291.     SetModifiedFlag();
  292. }
  293.  
  294. void CDbCtrl::OnQueryChanged() 
  295. {
  296.     SetModifiedFlag();
  297.     return;
  298. }
  299.  
  300.  
  301. void CDbCtrl::ReQuery() 
  302. {
  303.     if (m_pRecordSet != NULL)
  304.     {
  305.         m_pRecordSet->Close();
  306.         delete m_pRecordSet;
  307.         m_pRecordSet = NULL;
  308.     }
  309.         
  310.     if (m_bConnected == TRUE)
  311.     {
  312.         m_cDatabase.Close();
  313.         m_bConnected = FALSE;
  314.     }
  315.  
  316.     TRY                                                                             
  317.     {
  318.         m_bConnected = m_cDatabase.Open(m_dataSource,
  319.             FALSE, TRUE, "ODBC;", FALSE);
  320.     }           
  321.     CATCH_ALL(e)
  322.     {
  323.         MessageBox("Threw an exception!", "CDatabase::Open()");
  324.         return;
  325.     }
  326.     END_CATCH_ALL
  327.  
  328.     m_pRecordSet = new CGenericSet(&m_cDatabase, &m_columnName);
  329.  
  330.     TRY
  331.     {
  332.         m_query = "SELECT " + m_columnName + " FROM " + m_tableName;
  333.  
  334.         m_pRecordSet->Open(CRecordset::snapshot,
  335.                 m_query, CRecordset::readOnly);
  336.  
  337.         if (m_pRecordSet->IsBOF())
  338.         {
  339.             MessageBox("The requested table has no records.");
  340.         }
  341.         else
  342.         {
  343.             BOOL bMemoryFlag = FALSE;
  344.  
  345.             while (!m_pRecordSet->IsEOF())
  346.             {
  347.             if (SendMessage(LB_ADDSTRING, 0,
  348.                 (LPARAM) (LPCSTR) m_pRecordSet->m_strCurrentValue) == LB_ERR)
  349.                 {
  350.                 bMemoryFlag = TRUE;
  351.                 break;
  352.                 }
  353.             m_pRecordSet->MoveNext();
  354.             }
  355.  
  356.             if (bMemoryFlag == TRUE)
  357.             {
  358.                 MessageBox("Warning:  Not all returned records are shown in the listbox.",
  359.                         "Out Of Memory");
  360.             }
  361.         }
  362.     }           
  363.     CATCH(CDBException, e)
  364.     {
  365.         if (strlen(e->m_strError) == 0 &&
  366.             strlen(e->m_strStateNativeOrigin) == 0)
  367.         {
  368.             char szErrorMsg[_MAX_PATH];
  369.             wsprintf(szErrorMsg, "ODBC Error %d\nError text was not availalbe from driver",
  370.                 e->m_nRetCode);
  371.             MessageBox(szErrorMsg, "CRecordset::Open()", MB_ICONEXCLAMATION);
  372.         }
  373.         else
  374.         {
  375.             MessageBox(e->m_strError + "\n" +
  376.                 e->m_strStateNativeOrigin, "CRecordset::Open()", MB_ICONEXCLAMATION);
  377.         }                    
  378.  
  379.         delete m_pRecordSet;
  380.         m_pRecordSet = NULL;
  381.     }
  382.     END_CATCH
  383. }
  384.